﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Shapes;

namespace datagrid.Controls
{
    public class DataGrid : System.Windows.Controls.DataGrid
    {
        private ItemsControl itemsControl;
        private ScrollViewer scrollViewer;

        private ScrollViewer ownScrrow;

        public object TotalItems
        {
            get { return (object)GetValue(TotalItemsProperty); }
            set { SetValue(TotalItemsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TotalItems.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TotalItemsProperty =
            DependencyProperty.Register("TotalItems", typeof(object), typeof(DataGrid), new PropertyMetadata(null, TotalItemsCallBack));


        public object OriginItemsSource { get; set; }

        public object ItemsSources
        {
            get { return (object)GetValue(ItemsSourcesProperty); }
            set { SetValue(ItemsSourcesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemsSurces.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourcesProperty =
            DependencyProperty.Register("ItemsSources", typeof(object), typeof(DataGrid), new PropertyMetadata(null, ItemsSourcesCallBack));

        private static void ItemsSourcesCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {


            DataGrid dataGrid = d as DataGrid;
            if (e.NewValue != null)
            {
                dataGrid.OriginItemsSource = e.NewValue;
                dataGrid.ItemsSource = e.NewValue as IEnumerable<object>;
                //隐藏图标
                foreach (var item2 in dataGrid.Columns)
                {
                    if (item2.Header is StackPanel panel)
                    {
                        for (int i = 0; i < panel.Children.Count; i++)
                        {
                            if (panel.Children[i] is Path path1)
                            {
                                if (path1.Tag != null && path1.Tag is string type)
                                {
                                    if (type == "filter")
                                    {
                                        path1.Visibility = Visibility.Collapsed;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                dataGrid.OriginItemsSource = null;
                dataGrid.ItemsSource = null;
            }
        }

        //private List<string> _totalItems;
        private static void TotalItemsCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid dataGrid = d as DataGrid;
            if (dataGrid.itemsControl != null)
            {
                if (e.NewValue != null)
                {
                    if (e.NewValue is List<string> totalItems)
                    {
                        //数组和对象都要转为数组;
                        //排序问题处理
                        System.Threading.Tasks.Task.Factory.StartNew(() =>
                        {
                            System.Threading.Thread.Sleep(1000);
                            Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                            {
                                List<DataGridTotal> dataGrids = new List<DataGridTotal>();
                                for (int i = 0; i < dataGrid.Columns.Count; i++)
                                {
                                    if (dataGrid.Columns[i].Visibility == Visibility.Visible)
                                    {
                                        if (totalItems != null && totalItems.Count >= i + 1 && totalItems[i] != null)
                                        {
                                            dataGrids.Add(new DataGridTotal { Width = dataGrid.Columns[i].ActualWidth, Content = totalItems[i], Index = dataGrid.Columns[i].DisplayIndex });
                                        }
                                        else
                                        {
                                            dataGrids.Add(new DataGridTotal { Width = dataGrid.Columns[i].ActualWidth, Content = "-", Index = dataGrid.Columns[i].DisplayIndex });
                                        }

                                    }
                                }
                                dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
                                dataGrid.itemsControl.ItemsSource = dataGrids;
                            }));
                        });
                    }
                    else if (e.NewValue is object obj)
                    {
                        System.Threading.Tasks.Task.Factory.StartNew(() =>
                        {
                            System.Threading.Thread.Sleep(1000);
                            Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                            {
                                List<DataGridTotal> dataGrids = new List<DataGridTotal>();
                                for (int i = 0; i < dataGrid.Columns.Count; i++)
                                {
                                    if (dataGrid.Columns[i].Visibility == Visibility.Visible)
                                    {
                                        var content = "-";
                                        if (obj.GetType().GetProperty(dataGrid.Columns[i].SortMemberPath) != null)
                                        {
                                            content = obj.GetType().GetProperty(dataGrid.Columns[i].SortMemberPath).GetValue(obj, null)?.ToString();
                                        }
                                        dataGrids.Add(new DataGridTotal { Width = dataGrid.Columns[i].ActualWidth, Content = string.IsNullOrEmpty(content) ? "-" : content, Index = dataGrid.Columns[i].DisplayIndex });

                                    }
                                }
                                dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
                                dataGrid.itemsControl.ItemsSource = dataGrids;
                            }));
                        });
                    }
                }
                else
                {
                    System.Threading.Tasks.Task.Factory.StartNew(() => {
                        System.Threading.Thread.Sleep(1000);
                        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                        {
                            List<DataGridTotal> dataGrids = new List<DataGridTotal>();
                            for (int i = 0; i < dataGrid.Columns.Count; i++)
                            {
                                if (dataGrid.Columns[i].Visibility == Visibility.Visible)
                                {
                                    dataGrids.Add(new DataGridTotal { Width = dataGrid.Columns[i].ActualWidth, Content = "-", Index = dataGrid.Columns[i].DisplayIndex });
                                }
                            }
                            dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
                            dataGrid.itemsControl.ItemsSource = dataGrids;
                        }));
                    });
                }
            }

        }

        public DataGrid()
        {

            Loaded += (e, s) => {
                ColumnDisplayIndexChanged += DataGrid_ColumnDisplayIndexChanged;
                if (ownScrrow != null && scrollViewer != null)
                {
                    ownScrrow.ScrollChanged += OwnScrrow_ScrollChanged;
                }

            };
            Unloaded += (e, s) => {
                ColumnDisplayIndexChanged -= DataGrid_ColumnDisplayIndexChanged;
                if (ownScrrow != null && scrollViewer != null)
                {
                    ownScrrow.ScrollChanged -= OwnScrrow_ScrollChanged;

                }
            };
        }


        //protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
        //{
        //    base.OnItemsSourceChanged(oldValue, newValue);
        //    List<DataGridTotal> dataGrids = new List<DataGridTotal>();
        //    Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff"));
        //    System.Threading.Tasks.Task.Factory.StartNew(() => {
        //        System.Threading.Thread.Sleep(500);
        //        Console.WriteLine(DateTime.Now.ToString("HH:mm:ss fff"));

        //        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
        //        {
        //            for (int i = 0; i < Columns.Count; i++)
        //            {
        //                if (Columns[i].Visibility == Visibility.Visible)
        //                {
        //                    dataGrids.Add(new DataGridTotal { Width = Columns[i].ActualWidth, Content = "-", Index = Columns[i].DisplayIndex });
        //                    Console.WriteLine("宽度:" + Columns[i].ActualWidth + "--" + Columns[i].Width + "--" + Items.Count);

        //                }
        //            }
        //            dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
        //            itemsControl.ItemsSource = dataGrids;
        //        }));             
        //    });         
        //}
        private void DataGrid_ColumnDisplayIndexChanged(object sender, DataGridColumnEventArgs e)
        {
            if (itemsControl != null)
            {
                if (TotalItems != null)
                {
                    List<DataGridTotal> dataGrids = new List<DataGridTotal>();

                    if (TotalItems is List<string> items)
                    {
                        for (int i = 0; i < Columns.Count; i++)
                        {
                            if (Columns[i].Visibility == Visibility.Visible)
                            {
                                dataGrids.Add(new DataGridTotal { Width = Columns[i].ActualWidth, Content = items[i], Index = Columns[i].DisplayIndex });
                            }
                        }
                    }
                    else if (TotalItems is object obj)
                    {
                        for (int i = 0; i < Columns.Count; i++)
                        {
                            if (Columns[i].Visibility == Visibility.Visible)
                            {
                                var content = "-";
                                if (obj.GetType().GetProperty(Columns[i].SortMemberPath) != null)
                                {
                                    content = obj.GetType().GetProperty(Columns[i].SortMemberPath).GetValue(obj, null)?.ToString();
                                }
                                dataGrids.Add(new DataGridTotal { Width = Columns[i].ActualWidth, Content = string.IsNullOrEmpty(content) ? "-" : content, Index = Columns[i].DisplayIndex });
                            }
                        }

                    }


                    dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
                    itemsControl.ItemsSource = dataGrids;
                }
                else
                {
                    List<DataGridTotal> dataGrids = new List<DataGridTotal>();
                    for (int i = 0; i < Columns.Count; i++)
                    {
                        if (Columns[i].Visibility == Visibility.Visible)
                        {
                            dataGrids.Add(new DataGridTotal { Width = Columns[i].ActualWidth, Content = "-", Index = Columns[i].DisplayIndex });
                        }
                    }
                    dataGrids = dataGrids.OrderBy(x => x.Index).ToList();
                    itemsControl.ItemsSource = dataGrids;
                }
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            itemsControl = GetTemplateChild("itemsControl") as ItemsControl;
            scrollViewer = GetTemplateChild("scrollViewer") as ScrollViewer;
            ownScrrow = GetTemplateChild("DG_ScrollViewer") as ScrollViewer;
        }
        private void OwnScrrow_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            /*
            Console.WriteLine("----------------------------");
            Console.WriteLine("ScrollableWidth:"+ownScrrow.ScrollableWidth);
            Console.WriteLine("ExtentWidth:"+ownScrrow.ExtentWidth);
            Console.WriteLine("VerticalOffset:" + ownScrrow.VerticalOffset);
            Console.WriteLine("HorizontalOffset:" + ownScrrow.HorizontalOffset);
            */
            DataGrid_ColumnDisplayIndexChanged(null, null);

            /*
            if (ownScrrow.ScrollableWidth != horOffset)
            {
                horOffset = ownScrrow.ScrollableWidth;
                //宽度发生改变 通知滚动条重新渲染
                Console.WriteLine(horOffset);
                DataGrid_ColumnDisplayIndexChanged(null, null);
            } 
            */
            scrollViewer.ScrollToHorizontalOffset((sender as ScrollViewer).HorizontalOffset);
        }

    }

}
